package com.cygsunri.wisdompark.callback.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cygsunri.common.EnumConstant;
import com.cygsunri.wisdompark.bussiniss.vo.BaseResult;
import com.cygsunri.wisdompark.callback.entity.DeviceTemplateData;
import com.cygsunri.wisdompark.callback.entity.HisAnalogs;
import com.cygsunri.wisdompark.callback.entity.YadaWaterData;
import com.cygsunri.wisdompark.callback.service.DeviceTemplateDatasService;
import com.cygsunri.wisdompark.callback.service.InfluxDBService;
import com.cygsunri.wisdompark.callback.service.ProcessingDataService;
import com.cygsunri.wisdompark.callback.vo.CallBackReqVO;
import com.cygsunri.wisdompark.mqtt.IMqttSender;
import com.cygsunri.wisdompark.socket.SocketService;
import com.cygsunri.wisdompark.util.Byte16Util;
import com.cygsunri.wisdompark.util.CRCCheckUtil;
import com.cygsunri.wisdompark.util.DateUtil;
import com.cygsunri.wisdompark.util.ModbusDataUtil;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

;

/**
 * <p>
 * ctwing 回调类
 * 前端控制器
 * </p>
 *
 * @author cygsunri
 * @since 2021-06-04
 */
@Slf4j
@Controller
@RequestMapping("/ctwing/")
public class CtwingController {

    @Autowired
    private IMqttSender iMqttSender;
    @Autowired
    private InfluxDBService influxDBService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DeviceTemplateDatasService deviceTemplateDataService;
    @Autowired
    private ProcessingDataService processingDataService;
    @Autowired
    private SocketService socketService;

    /**
     * 安科瑞电表回调
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/ankerui", method = RequestMethod.POST)
    public ResponseEntity<?> ankerui(@RequestBody CallBackReqVO callBackReqVO) {
        try {
            if (callBackReqVO.getPayload().isEmpty()) {
                BaseResult data = new BaseResult();
                data.setCode(EnumConstant.CallBackResult.FAILURE.getValue());
                return new ResponseEntity<>(data, HttpStatus.OK);
            }
            List<DeviceTemplateData> deviceTemplateDataList = deviceTemplateDataService.findDataByPsrID(callBackReqVO.getDeviceId());
            Map<String, Object> resultMap = ModbusDataUtil.ankeruiModbusData(callBackReqVO.getPayload().get("APPdata").toString(), deviceTemplateDataList);
            //保存数据
            processingDataService.saveData(callBackReqVO.getDeviceId(), resultMap, "ankerui");
            return new ResponseEntity<>(resultMap, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
        }
        BaseResult data = new BaseResult();
        data.setCode(EnumConstant.CallBackResult.SUCCESS.getValue());
        return new ResponseEntity<>(data, HttpStatus.OK);
    }


    /**
     * 雅达电表回调
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/yada", method = RequestMethod.POST)
    public ResponseEntity<?> yada(@RequestBody CallBackReqVO callBackReqVO) {
        try {
            if (callBackReqVO.getPayload() == null || callBackReqVO.getPayload().isEmpty()) {
                BaseResult data = new BaseResult();
                data.setCode(EnumConstant.CallBackResult.FAILURE.getValue());
                return new ResponseEntity<>(data, HttpStatus.OK);
            }
            List<DeviceTemplateData> deviceTemplateDataList = deviceTemplateDataService.findDataByPsrID(callBackReqVO.getDeviceId());
//            DeviceTemplate deviceTemplate = deviceTemplateService.findDataByPsrID(callBackReqVO.getDeviceId());
                Map<String, Object> resultMap = ModbusDataUtil.yadaModbusData(callBackReqVO.getPayload().get("APPdata").toString(), deviceTemplateDataList);
            //保存数据
            processingDataService.saveData(callBackReqVO.getDeviceId(), resultMap, "yada");
            return new ResponseEntity<>(resultMap, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
        }
        BaseResult data = new BaseResult();
        data.setCode(EnumConstant.CallBackResult.SUCCESS.getValue());
        return new ResponseEntity<>(data, HttpStatus.OK);
    }


    /**
     * 雅达水表回调
     *
     * @param
     * @return
     */
    @RequestMapping(value = "/yadaWater", method = RequestMethod.POST)
    public ResponseEntity<?> yadaWater(@RequestBody CallBackReqVO callBackReqVO) {
        try {
            //消息类型校验
            if (!EnumConstant.ctwingMessageType.dataReport.getValue().equals(callBackReqVO.getMessageType()) && !EnumConstant.ctwingMessageType.dataReportTupUnion.getValue().equals(callBackReqVO.getMessageType())) {
                BaseResult data = new BaseResult();
                data.setCode(EnumConstant.CallBackResult.FAILURE.getValue());
                return new ResponseEntity<>(data, HttpStatus.OK);
            }
            //消息体格式校验
            if (callBackReqVO.getPayload() == null || callBackReqVO.getPayload().isEmpty()) {
                BaseResult data = new BaseResult();
                data.setCode(EnumConstant.CallBackResult.FAILURE.getValue());
                return new ResponseEntity<>(data, HttpStatus.OK);
            }
            JSONObject serviceData = callBackReqVO.getPayload().getJSONObject("serviceData");
            YadaWaterData yadaWaterData = JSONObject.parseObject(serviceData.toJSONString(), YadaWaterData.class);
            yadaWaterData.setTime(callBackReqVO.getTimestamp());
            //保存数据
            processingDataService.saveData(callBackReqVO.getDeviceId(), JSON.parseObject(new Gson().toJson(yadaWaterData), HashMap.class), "yadaWater");
            return new ResponseEntity<>(yadaWaterData, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
        }
        BaseResult data = new BaseResult();
        data.setCode(EnumConstant.CallBackResult.SUCCESS.getValue());
        return new ResponseEntity<>(data, HttpStatus.OK);
    }


    /**
     * 读取redis中的设备数据
     *
     * @param deviceId
     * @param name
     * @return
     */
    @RequestMapping(value = "/queryDataByDeviceId", method = RequestMethod.GET)
    public ResponseEntity<?> queryDataByDeviceId(String deviceId, String name) {
        Map resultMap = new HashMap();
        String key = String.format("means/%1$s/%2$s", deviceId, name);
        Object value = redisTemplate.opsForValue().get(key);
        resultMap.put(name, value);
        return new ResponseEntity<>(resultMap, HttpStatus.OK);
    }

    /**
     * 读取influxdb中的设备历史数据
     *
     * @param deviceId
     * @param name     name=all全取
     * @return
     */
    @RequestMapping(value = "/queryHistoryDataByDeviceId/{deviceId}/{name}", method = RequestMethod.GET)
    public ResponseEntity<?> queryHistoryDataByDeviceId(@PathVariable("deviceId") String deviceId, @PathVariable("name") String name) {
        List<HisAnalogs> list = influxDBService.queryHisAnalogs(deviceId, name);
        return new ResponseEntity<>(list, HttpStatus.OK);
    }


    // 发送自定义消息内容，且指定主题
    @RequestMapping("/mqtt3/{topic}/{payload}")
    public void test21(@PathVariable("topic") String topic, @PathVariable("payload") String payload) {
        byte[] bytes = Byte16Util.toByteArray(payload);
        String crcCheck = CRCCheckUtil.Make_CRC(bytes);
        iMqttSender.sendToMqtt("theme/device/air/" + topic, "{\"payload\":\"" + payload + crcCheck + "\",\"oper\":\"coll1\",\"batch\":\" fe411e0b988547cfb324a7fa5efd64c7\"}");
    }


    // 设置message
    @RequestMapping("/updateMessage/{message}")
    public ResponseEntity<?> updateMessage(@PathVariable("message") String message) {
        byte[] bytes = Byte16Util.toByteArray(message);
        String crcCheck = CRCCheckUtil.Make_CRC(bytes);
//        redisTemplate.opsForValue().set("socketMessage", message + crcCheck);
        Map resultMap = new HashMap();
        resultMap.put("socketMessage", message + crcCheck);
        return new ResponseEntity<>(resultMap, HttpStatus.OK);
    }


    // 发送自定义消息内容，且指定主题
    @RequestMapping("/test")
    public ResponseEntity<?> test() {
        redisTemplate.opsForHash().put("1111111", "1", 10000);
        redisTemplate.opsForHash().put("1111111", "3", 10000);
        redisTemplate.opsForHash().put("1111111", "4", 10000);
        Map map = new HashMap();
        map.put("1", 1);
        map.put("2", 2);
        redisTemplate.opsForHash().putAll("1111111", map);
        Map resultMap = new HashMap();
        Map map1 = redisTemplate.opsForHash().entries("11122221111");
        if (map1.isEmpty()) {
            log.info("dfsafdasdfasddfds");
        }
        resultMap = redisTemplate.opsForHash().entries("1111111");

        return new ResponseEntity<>(resultMap, HttpStatus.OK);
    }


    /**
     * 读取redis中的设备数据
     *
     * @param
     * @param
     * @return
     */
    @RequestMapping(value = "/queryDataByDeviceIds", method = RequestMethod.GET)
    public ResponseEntity<?> queryDataByDeviceIds(String deviceIds) {
        Map resultMap = new HashMap();
        if (StringUtils.isNotEmpty(deviceIds)) {
            for (String deviceId : deviceIds.split(",")) {
                Map temp = redisTemplate.opsForHash().entries(deviceId);
                if (!temp.isEmpty()) {
                    String longTime = temp.get("time").toString();
                    String time = DateUtil.stampToDate(longTime);
                    temp.put("time", time);
                }
                resultMap.put(deviceId, temp);
            }
        }
        return new ResponseEntity<>(resultMap, HttpStatus.OK);
    }


    /**
     * 发送消息给tcp服务接口
     *
     * @param
     * @param
     * @return
     */
    @RequestMapping(value = "/sendMessageToTcp", method = RequestMethod.GET)
    public ResponseEntity<?> sendMessageToTcp(String message) {
        Map resultMap = new HashMap();
        socketService.sendMessage(message);
        return new ResponseEntity<>(resultMap, HttpStatus.OK);
    }

}
